package cn.italkcloud.cph.entity.wrapper;

import cn.italkcloud.cph.constants.enums.vos.CustomerTypeEnum;
import cn.italkcloud.cph.constants.enums.vos.FeeLogTypeEnum;
import cn.italkcloud.cph.constants.enums.vos.LockTypeEnum;
import cn.italkcloud.cph.entity.*;
import cn.italkcloud.cph.entity.dto.VosCustomerDTO;
import cn.italkcloud.cph.entity.dto.VosCustomerGroupDTO;
import cn.italkcloud.cph.entity.dto.VosFeeLogDTO;
import cn.italkcloud.cph.entity.dto.VosServerDTO;
import cn.italkcloud.cph.entity.dto.vos.CustomerDetailDTO;
import cn.italkcloud.cph.entity.dto.vos.PayHistoryDTO;
import cn.italkcloud.cph.entity.dto.vos.ReportCdrDTO;
import cn.italkcloud.cph.entity.dto.vos.ReportCustomerFeeDTO;
import cn.italkcloud.cph.helper.UserHelper;
import cn.italkcloud.cph.utils.BaseUtil;
import cn.italkcloud.cph.utils.StringUtil;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author dominate
 * @since 2024/7/9
 **/
public class VosWrapper {

    public static VosWrapper builder() {
        return new VosWrapper();
    }

    private static long findMinTime(long time1, long time2, long time3) {
        if (time1 < time2) {
            return Math.min(time1, time3);
        }
        return Math.min(time2, time3);
    }

    private static long findMaxTime(long time1, long time2, long time3) {
        if (time1 > time2) {
            return Math.max(time1, time3);
        }
        return Math.max(time2, time3);
    }

    public ReportCdrDTO entityDTO(ReportVosCdr entity) {
        ReportCdrDTO target = new ReportCdrDTO();
        BaseUtil.set(target, entity);
        target.setEndTime(entity.getEndTime().getTime());
        target.setStartTime(entity.getStartTime().getTime());
        return target;
    }

    public List<ReportCdrDTO> entityReportCdrDTO(List<ReportVosCdr> entityList) {
        List<ReportCdrDTO> list = new ArrayList<>(entityList.size());
        for (ReportVosCdr entity : entityList) {
            list.add(entityDTO(entity));
        }
        return list;
    }

    public VosCustomer entityDTO(CustomerDetailDTO entity) {
        VosCustomer target = new VosCustomer();
        BaseUtil.set(target, entity);
        target.setVosAccount(entity.getAccount());
        target.setVosName(entity.getName());
        target.setStartTime(new Date(entity.getStartTime()));
        target.setValidTime(new Date(entity.getValidTime()));
        return target;
    }

    public List<VosCustomerDTO> merge(List<VosCustomer> entityList, List<String> vosAccountList) {
        List<VosCustomerDTO> list = new ArrayList<>(entityList.size());
        Set<String> unbindVosAccountList = new HashSet<>(vosAccountList);
        for (VosCustomer entity : entityList) {
            list.add(entityDTO(entity));
            unbindVosAccountList.remove(entity.getVosAccount());
        }
        for (String vosAccount : unbindVosAccountList) {
            VosCustomerDTO entity = new VosCustomerDTO(vosAccount);
            list.add(entity);
        }
        return list;
    }

    public List<VosCustomerGroupDTO> entityCustomerGroupDTO(List<VosCustomerGroup> entityList) {
        List<VosCustomerGroupDTO> list = new ArrayList<>(entityList.size());
        for (VosCustomerGroup entity : entityList) {
            list.add(entityDTO(entity));
        }
        return list;
    }

    public VosCustomerGroupDTO entityDTO(VosCustomerGroup entity) {
        VosCustomerGroupDTO target = new VosCustomerGroupDTO();
        BaseUtil.set(target, entity);
        if (Objects.nonNull(entity.getCreateTime())) {
            target.setCreateTime(entity.getCreateTime().getTime());
            target.setUpdateTime(entity.getUpdateTime().getTime());
        }
        return target;
    }

    public List<VosServerDTO> entityServerDTO(List<VosServer> entityList) {
        List<VosServerDTO> list = new ArrayList<>(entityList.size());
        for (VosServer entity : entityList) {
            list.add(entityDTO(entity));
        }
        return list;
    }

    public VosServerDTO entityDTO(VosServer entity) {
        VosServerDTO target = new VosServerDTO();
        BaseUtil.set(target, entity);
        if (0 != entity.getAccountId()) {
            target.setAccountName(UserHelper.getUserName(entity.getAccountId()));
        }
        if (Objects.nonNull(entity.getCreateTime())) {
            target.setCreateTime(entity.getCreateTime().getTime());
            target.setUpdateTime(entity.getUpdateTime().getTime());
        }
        return target;
    }

    public List<VosCustomerDTO> entityCustomerDTO(List<VosCustomer> entityList, Map<Integer, String> serverNameMap) {
        List<VosCustomerDTO> list = new ArrayList<>(entityList.size());
        for (VosCustomer entity : entityList) {
            VosCustomerDTO target = entityDTO(entity);
            if (Objects.nonNull(target.getServerId())) {
                target.setServerName(serverNameMap.getOrDefault(target.getServerId(), StringUtil.EMPTY));
            }
            list.add(target);
        }
        return list;
    }

    public List<VosCustomerDTO> entityCustomerDTO(List<VosCustomer> entityList) {
        List<VosCustomerDTO> list = new ArrayList<>(entityList.size());
        for (VosCustomer entity : entityList) {
            list.add(entityDTO(entity));
        }
        return list;
    }

    public VosCustomerDTO entityDTO(VosCustomer entity) {
        VosCustomerDTO target = new VosCustomerDTO();
        BaseUtil.set(target, entity);
        if (0 != entity.getAccountId()) {
            target.setAccountName(UserHelper.getUserName(entity.getAccountId()));
        }
        target.setTypeName(CustomerTypeEnum.getName(entity.getType()));
        target.setLockTypeName(LockTypeEnum.getName(entity.getLockType()));
        target.setStartTime(entity.getStartTime().getTime());
        target.setValidTime(entity.getValidTime().getTime());
        return target;
    }

    public VosFeeLog createFeeLog(FeeLogTypeEnum feeType, BigDecimal change, BigDecimal balance, VosCustomer vosCustomer) {
        return createFeeLog(feeType, change, balance, vosCustomer, StringUtil.EMPTY);
    }

    public VosFeeLog createFeeLog(FeeLogTypeEnum feeType, PayHistoryDTO payLog, VosCustomer vosCustomer) {
        return createFeeLog(feeType, payLog.getFee(), payLog.getCustomerMoney(), vosCustomer, payLog.getMemo());
    }

    public VosFeeLog createFeeLog(FeeLogTypeEnum feeType, BigDecimal change, BigDecimal balance, VosCustomer vosCustomer, String comment) {
        return new VosFeeLog()
                .setAccountId(vosCustomer.getAccountId())
                .setVosCustomerId(vosCustomer.getId())
                .setType(feeType.getCode())
                .setChange(change)
                .setBalance(balance)
                .setComment(comment);
    }

    public ReportCustomerFeeDTO merge(List<ReportCustomerFeeDTO> feeList) {
        ReportCustomerFeeDTO merge = new ReportCustomerFeeDTO();
        for (ReportCustomerFeeDTO fee : feeList) {
            if (StringUtil.isEmpty(merge.getAccount())) {
                merge.setAccount(fee.getAccount());
            }
            if (StringUtil.isEmpty(merge.getAccountName())) {
                merge.setAccountName(fee.getAccountName());
            }
            merge.setCdrCount(merge.getCdrCount() + fee.getCdrCount());
            merge.setTotalTime(merge.getTotalTime() + fee.getTotalTime());
            merge.setTotalFee(merge.getTotalFee().add(fee.getTotalFee()));
            if (null == merge.getBeginTime()) {
                merge.setBeginTime(fee.getBeginTime());
            }
            if (null == merge.getEndTime()) {
                merge.setEndTime(fee.getEndTime());
            }
            merge.setBeginTime(findMinTime(fee.getBeginTime(), fee.getEndTime(), merge.getBeginTime()));
            merge.setEndTime(findMaxTime(fee.getBeginTime(), fee.getEndTime(), merge.getEndTime()));

        }
        return merge;
    }

    public List<VosFeeLogDTO> entityFeeLogDTO(List<VosFeeLog> entityList, Map<Integer, String> vosAccountMap) {
        List<VosFeeLogDTO> list = new ArrayList<>(entityList.size());
        for (VosFeeLog entity : entityList) {
            VosFeeLogDTO entityDTO = entityDTO(entity);
            entityDTO.setVosAccount(vosAccountMap.getOrDefault(entity.getVosCustomerId(), StringUtil.EMPTY));
            list.add(entityDTO);
        }
        return list;
    }

    public VosFeeLogDTO entityDTO(VosFeeLog entity) {
        VosFeeLogDTO target = new VosFeeLogDTO();
        BaseUtil.set(target, entity);
        if (0 != entity.getAccountId()) {
            target.setAccountName(UserHelper.getUserName(entity.getAccountId()));
        }
        target.setTypeName(FeeLogTypeEnum.getName(entity.getType()));
        target.setCreateTime(entity.getCreateTime().getTime());
        target.setUpdateTime(entity.getUpdateTime().getTime());
        return target;
    }
}
